/**
 * Defines the state and behavior of a king piece.
 * 
 * @author Sarangan Balasubramaniam
 * @version 1.16
 */
package pieces;
import mainClasses.*;

import java.awt.Point;
import java.lang.Math;
public class King extends Piece{
	
	public boolean firstMove = true;
	public boolean castlingPossible = false;
	public boolean castlingPossible2 = false;
	private Rook rookCastling;
	private Rook rookCastling2;
	private Point location = new Point(10, 10);
	private Point location2 = new Point(10, 10);
	private Point rookDestination;
	private Point rookDestination2;
	/**
	 * Constructor for the king class which create the king object
	 * If the colour is white then it is player 1's piece
	 * If the colour is black then it is player 2's piece
	 * 
	 * @param xaxis - x value of location of this piece
	 * @param yaxis - y value of location of this piece
	 * @param b - It is the board which the piece will be placed in.
	 * @param color - It represent the side of the piece
	 */
	public King(int xaxis, int yaxis, Board board, String color)
	{
		super(xaxis, yaxis, board, "   King  ", color);
		if(color!="White")
		{
			super.type = "BK-->King";
			
		}
	}
	
	
	/** 
	 * This calculate if this piece can be moved a given location
	 * 
     * @param p2 - Destination of this piece on the board
     * @return A boolean value to determine if the piece can be moved or not
     */
	
	public boolean movePossible(int desX, int desY)
	{
		Piece piece = new NullPiece(0, 0, this.board);
		Piece piece2 = new NullPiece(0, 0, this.board);
		if(this.firstMove && !this.board.getkingInDanger())
		{
			for(int i = 0; i<8; i++)
			{
				for(int j = 0; j<8; j++)
				{
					if((this.board.getPiece(i, j) instanceof Rook) && (Math.abs(this.y-j)==3) && (this.board.getPiece(i, j).getSide().equals(this.side)))
					{
						piece = this.board.getPiece(i, j);
						this.setRookCastling((Rook)piece);
						
						
					}else if((this.board.getPiece(i, j) instanceof Rook) && (Math.abs(this.y-j)==4) && (this.board.getPiece(i, j).getSide().equals(this.side)))
					{
						piece2 = this.board.getPiece(i, j);
						this.setRookCastling2((Rook)piece2);
						
						
					}
				}
			}
			if((piece instanceof Rook))
			{
				Rook rook  = (Rook)piece;
				if(rook.isFirstMove())
				{
					this.setCastlingPossible(true);
				}else 
				{
					this.setCastlingPossible(false);
				}
				
			}
			if((piece2 instanceof Rook))
			{
				Rook rook2  = (Rook)piece2;	
				if(rook2.isFirstMove())
				{
					this.castlingPossible2 = true;
				}else
				{
					this.castlingPossible2 = false;
				}
			}
		}else
		{
			this.setCastlingPossible(false);
			this.castlingPossible2 = false;
		}
		
		
		if(desX>7||desX<0||desY>7||desY<0)
        {
        	return false;
        }
        else if(this.board.getPiece(desX, desY) instanceof NullPiece||this.isEnemy(desX, desY))	//only can be moved if the destination is an enemy or Nullpiece
		{
        	if(Math.abs(super.x-desX)+Math.abs(super.y-desY)==1)	//if only one block up, down, left, right
			{
				if(super.board.getPiece(desX, desY).side=="None")	//check if the destination is empty
				{
					return true;			
				}else if(super.board.getPiece(desX, desY).getSide()!=super.getSide())	//check if the destination is not a piece that is the same side as this one
				{
					return true;	//if it is then move is possible
				}
				else //other wise can't move there
				{
					return false;
				}
			}else if(Math.abs(super.x-desX)==0 && (super.y-desY== (0-2)) && this.castlingPossible && this.side.equals("White")) //check if it is a one block in diagonal move
			{

				if(((piece.getY()-1)==desY))
				{
					this.setLocation(new Point(desX, desY));
					this.setRookDestination(new Point(this.x, (piece.getY()-2)));
					return true;
				}else if((piece.getY()+1)==desY)
				{
					this.setLocation(new Point(desX, desY));
					this.setRookDestination(new Point(this.x, (piece.getY()+2)));
					return true;
				}
			}else if(Math.abs(super.x-desX)==0 && (super.y-desY == -2) && this.castlingPossible && this.side.equals("Black")) //check if it is a one block in diagonal move
			{

				if(((piece.getY()-1)==desY))
				{
					this.setLocation(new Point(desX, desY));
					this.setRookDestination(new Point(this.x, (piece.getY()-2)));
					return true;
				}else if((piece.getY()+1)==desY)
				{
					this.setLocation(new Point(desX, desY));
					this.setRookDestination(new Point(this.x, (piece.getY()+2)));
					return true;
				}
			}else if(Math.abs(super.x-desX)==0 && (super.y-desY== 2) && this.castlingPossible2 && this.side.equals("White")) //check if it is a one block in diagonal move
			{

				if(((piece2.getY()-2)==desY))
				{
					this.setLocation2(new Point(desX, desY));
					this.setRookDestination2(new Point(this.x, (piece2.getY()-3)));
					return true;
				}else if((piece2.getY()+2)==desY)
				{
					this.setLocation2(new Point(desX, desY));
					this.setRookDestination2(new Point(this.x, (piece2.getY()+3)));
					return true;
				}
			}else if(Math.abs(super.x-desX)==0 && (super.y-desY== 2) && this.castlingPossible2 && this.side.equals("Black")) //check if it is a one block in diagonal move
			{

				if(((piece2.getY()-2)==desY))
				{
					this.setLocation2(new Point(desX, desY));
					this.setRookDestination2(new Point(this.x, (piece2.getY()-3)));
					return true;
				}else if((piece2.getY()+2)==desY)
				{
					this.setLocation2(new Point(desX, desY));
					this.setRookDestination2(new Point(this.x, (piece2.getY()+3)));
					return true;
				}
			}else if(Math.abs(super.x-desX)==1 && Math.abs(super.y-desY)== 1) //check if it is a one block in diagonal move
			{
				return true;	//if it is then move is possible
			}
			else if((Math.abs(super.x-desX)+Math.abs(super.y-desY))>= 2)	//check if it is moving more than one block
			{
				return false;	//if it is then move is not possible
			}
			return false;
		}else return false;
	}

	/**
	 * set the firstMove parameter with given boolean
	 * 
	 * @param firstMove - this will replace the firstMove parameter
	 */
	public void setFirstMove(boolean firstMove) {
		this.firstMove = firstMove;
	}

	/**
	 * return the firstmove parameter to other classes
	 * 
	 * @return firstMove - return the firstmove parameter
	 */
	public boolean getFirstMove() {
		return firstMove;
	}


	/**
	 * @param castlingPossible the castlingPossible to set
	 */
	public void setCastlingPossible(boolean castlingPossible) {
		this.castlingPossible = castlingPossible;
	}


	/**
	 * @return the castlingPossible
	 */
	public boolean isCastlingPossible() {
		return castlingPossible;
	}


	/**
	 * @param rookCastling the rookCastling to set
	 */
	public void setRookCastling(Rook rookCastling) {
		this.rookCastling = rookCastling;
	}


	/**
	 * @return the rookCastling
	 */
	public Rook getRookCastling() {
		return rookCastling;
	}


	/**
	 * @param location the location to set
	 */
	public void setLocation(Point location) {
		this.location = location;
	}


	/**
	 * @return the location
	 */
	public Point getLocation() {
		return location;
	}


	/**
	 * @param rookDestination the rookDestination to set
	 */
	public void setRookDestination(Point rookDestination) {
		this.rookDestination = rookDestination;
	}


	/**
	 * @return the rookDestination
	 */
	public Point getRookDestination() {
		return rookDestination;
	}


	/**
	 * @param rookCastling2 the rookCastling2 to set
	 */
	public void setRookCastling2(Rook rookCastling2) {
		this.rookCastling2 = rookCastling2;
	}


	/**
	 * @return the rookCastling2
	 */
	public Rook getRookCastling2() {
		return rookCastling2;
	}


	/**
	 * @param rookDestination2 the rookDestination2 to set
	 */
	public void setRookDestination2(Point rookDestination2) {
		this.rookDestination2 = rookDestination2;
	}


	/**
	 * @return the rookDestination2
	 */
	public Point getRookDestination2() {
		return rookDestination2;
	}


	/**
	 * @param location2 the location2 to set
	 */
	public void setLocation2(Point location2) {
		this.location2 = location2;
	}


	/**
	 * @return the location2
	 */
	public Point getLocation2() {
		return location2;
	}
}

